using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace MKDS_Course_Editor.Players
{
    public class MusicPlayer
    {
        DirectMidi.CDirectMusic CDMusic = new DirectMidi.CDirectMusic();
        DirectMidi.CDLSLoader CLoader = new DirectMidi.CDLSLoader();
        DirectMidi.COutputPort COutPort = new DirectMidi.COutputPort();
        DirectMidi.CAPathPerformance CAPathPerformance = new DirectMidi.CAPathPerformance();
        DirectMidi.CCollection CCollectionA = new DirectMidi.CCollection();
        DirectMidi.CSegment CSegment1 = new DirectMidi.CSegment();
        DirectMidi.INFOPORT PortInfo;
        public MusicPlayer()
        {
            // Initializes DirectMusic
            CDMusic.Initialize();
            // Initializes an audiopath performance
            CAPathPerformance.Initialize(CDMusic, null, null, DirectMidi.DMUS_APATH.DYNAMIC_STEREO, 128);
            // Initializes a port performance object
            //CPortPerformance.Initialize(CDMusic, null, null);
            // Initializes loader object
            CLoader.Initialize();
            // Initializes output port
            COutPort.Initialize(CDMusic);
            // Selects the first software synthesizer port
            //uint dwPortCount = 0;
            //do
            //COutPort.GetPortInfo(dwPortCount, out PortInfo);
            //while (!(PortInfo.dwFlags.HasFlag(DirectMidi.DMUS_PC.SOFTWARESYNTH)));
            //cout << "Selected output port: " << PortInfo.szPortDescription << endl;
            //COutPort.SetPortParams(0, 0, 0, DirectMidi.SET.REVERB | DirectMidi.SET.CHORUS, 44100);
            //COutPort.ActivatePort(PortInfo);
            // Adds the selected port to the performance
            //CAPathPerformance.AddPort(COutPort, 0, 1);
        }
        private bool UseDLS = false;
        string DLS = "";
        string Midi = "";
        public void SetDLS(string Path)
        {
            //DLS = Path;
            DLS = System.IO.Path.GetTempFileName();
            System.IO.File.Copy(Path, DLS, true);
            UseDLS = true;
        }
        public void UnloadDLS()
        {
            UseDLS = false;
        }
        public void SetMidi(string Path)
        {
            Midi = Path;
        }
        public int GetLength()
        {
            if (CAPathPerformance != null)
            {
                CAPathPerformance.StopAll();
            }
            CSegment1.ReleaseSegment();
            CSegment1.UnloadAllPerformances();
            CLoader.UnloadCollection(CCollectionA);
            CLoader.LoadSegment(Midi, out CSegment1, true);
            if (UseDLS)
            {
                CLoader.LoadDLS(DLS, out CCollectionA);
                CSegment1.ConnectToDLS(CCollectionA);
            }
            CSegment1.Download(CAPathPerformance);
            int o;
            CSegment1.GetLength(out o);
            return o;
        }
        public void Play()
        {
            if (CAPathPerformance != null)
            {
                CAPathPerformance.StopAll();
            }
            CSegment1.ReleaseSegment();
            CSegment1.UnloadAllPerformances();
            CLoader.UnloadCollection(CCollectionA);
            CLoader.LoadSegment(Midi, out CSegment1, true);
            if (UseDLS)
            {
                CLoader.LoadDLS(DLS, out CCollectionA);
                CSegment1.ConnectToDLS(CCollectionA);
            }
            CSegment1.Download(CAPathPerformance);
            if (useLoop)
            {
                CSegment1.SetLoopPoints(LoopStart, LoopEnd);
                if (times != -1)
                {
                    CSegment1.SetRepeats((uint)times);
                }
                else
                {
                    CSegment1.SetRepeats(DirectMidi.DMUS_SEG.REPEAT_INFINITE);
                }
            }
            CAPathPerformance.PlaySegment(CSegment1, null);
        }
        bool useLoop = false;
        int LoopStart;
        int LoopEnd;
        int times;
        public void SetLoop(int Start, int End, int times)
        {
            useLoop = true;
            LoopEnd = End;
            this.times = times;
            LoopStart = Start;
        }
        public void Unload()
        {
            UseDLS = false;
            useLoop = false;
            Midi = "";
            times = -1;
            if (CAPathPerformance != null)
            {
                CAPathPerformance.StopAll();
            }
            CSegment1.ReleaseSegment();
            CSegment1.UnloadAllPerformances();
            /*List<DirectMidi.CInstrument> c = new List<DirectMidi.CInstrument>();
            int nr = 0;
            DirectMidi.CInstrument ins = null;
            do
            {
                if (ins != null)
                {
                    c.Add(ins);
                }
                CCollectionA.GetInstrument(out ins, nr);
                nr++;
            }
            while (ins == null);
            for (int i = 0; i < c.Count; i++)
            {
                CAPathPerformance.UnloadInstrument(c[i]);
            }*/
            CLoader.UnloadCollection(CCollectionA);
            COutPort.ReleasePort();

            //CDMusic = new DirectMidi.CDirectMusic();
            //CLoader = new DirectMidi.CDLSLoader();
            //CAPathPerformance = new DirectMidi.CAPathPerformance();
            CSegment1 = null;
            CLoader = null;
            CCollectionA = null;
            if (UseDLS)
            {
                System.IO.File.Delete(DLS);
            }
            DLS = "";
            CSegment1 = new DirectMidi.CSegment();
            CLoader = new DirectMidi.CDLSLoader();
            CCollectionA = new DirectMidi.CCollection();
            // Initializes DirectMusic
            //CDMusic.Initialize();
            // Initializes an audiopath performance
            //CAPathPerformance.Initialize(CDMusic, null, parent, DirectMidi.DMUS_APATH.DYNAMIC_STEREO, 128);
            // Initializes a port performance object
            //CPortPerformance.Initialize(CDMusic, null, null);
            // Initializes loader object
            CLoader.Initialize();
        }
        public void Stop()
        {
            CAPathPerformance.StopAll();
        }
    }
}
